package com.song.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 常用字符串工具类
 */
public class StringUtil {
    /**
     * 判断字符串为空
     *
     * @param source
     * @return
     */
    public static boolean isNullOrEmpty(String source) {
        if (source == null || "".equals(source)) {
            return true;
        }
        return false;
    }

    /**
     * 判断字符串不为空
     *
     * @param source
     * @return
     */
    public static boolean isNotNullOrEmpty(String source){
        return !isNullOrEmpty(source);
    }

    /**
     * 生成一个指定长度不以0开头的随机Long型数据
     *
     * @param length
     * @return
     */
    public static Long generateRandomLong(int length) {
        StringBuffer buffer = new StringBuffer();
        Random random = new Random();
        int randNum = random.nextInt(9) + 1;
        buffer.append(randNum);
        for (int i = 1; i < length; i++) {
            randNum = random.nextInt(10);
            buffer.append(randNum);
        }
        return new Long(buffer.toString());
    }

    /**
     * 生成指定长度的数字随机字符串
     *
     * @param length
     * @return
     */
    public static String generateRandomString(int length) {
        StringBuffer buffer = new StringBuffer();
        Random random = new Random();
        int randNum = 0;
        for (int i = 0; i < length; i++) {
            randNum = random.nextInt(10);
            buffer.append(randNum);
        }
        return buffer.toString();
    }

    /**
     * 生成指定长度[A-Z][a-z][0-9]随机字符串
     *
     * @param length
     * @return
     */
    public static String generateRandomStr(int length) {
        StringBuffer buffer = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            String choice = random.nextInt(2) == 0 ? "char" : "num";
            if ("char".equalsIgnoreCase(choice)) {
                int start = random.nextInt(2) == 0 ? 65 : 97;
                buffer.append((char) (start + random.nextInt(26)));
            } else if ("num".equalsIgnoreCase(choice)) {
                buffer.append(random.nextInt(10));
            }
        }
        return buffer.toString();
    }

    /**
     * 生成指定长度[A-Z][a-z][0-9][~!@#$%^&*.?]的字符串
     *
     * @param length
     * @return
     */
    public static String generateRandomStringSpecial(int length) {
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~!@#$%^&*.?".toCharArray();
        StringBuffer buffer = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            buffer.append(chars[random.nextInt(chars.length)]);
        }
        return buffer.toString();
    }

    /**
     * 字符串首字母大写
     *
     * @param source
     * @return
     */
    public static String upperFirstChar(String source) {
        if (isNullOrEmpty(source)) {
            return source;
        }
        return source.substring(0, 1).toUpperCase() + source.substring(1);
    }

    /**
     * 浮点数转为字符串
     *
     * @param d
     * @return
     */
    public static String format(Double d) {
        if (d - d.intValue() == 0) {
            return String.valueOf(d.intValue());
        }
        return String.valueOf(d);
    }

    /**
     * 身份证计算年龄
     * @param idCard
     * @return
     */
    public static int countAge(String idCard) {
        if (idCard.length() != 18 && idCard.length() != 15) {
            throw new IllegalArgumentException("身份证号长度错误");
        }
        String year;
        String monthDay;
        if (idCard.length() == 18) {
            year = idCard.substring(6, 10);
            monthDay = idCard.substring(10, 14);
        } else {
            year = "19" + idCard.substring(6, 8);
            monthDay = idCard.substring(8, 12);
        }
        //获取当前时间字符串如：20230101
        String nowTimeStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String yearNow = nowTimeStr.substring(0, 4);// 当前年份
        String monthDayNow = nowTimeStr.substring(4, 8);// 当前月日
        int age = Integer.parseInt(yearNow) - Integer.parseInt(year);
        //age减一的情况 ：用户月日大于当前月日（开头可以为0的4位数int）
        if (Integer.parseInt(monthDay) > Integer.parseInt(monthDayNow)) {
            age = age - 1;
        }
        return age;
    }

    /**
     * 身份证号获取性别
     * @param idCard
     * @return
     */
    public static String getGender(String idCard){
        if (Integer.valueOf(idCard.substring(16, 17)) % 2 == 0){
            return "0";
        }
        return "1";
    }

    /**
     * 检查身份证号是否合规
     * @param idCard
     * @return
     * @throws ParseException
     */
    public static boolean checkIdCard(String idCard) throws ParseException {
        if (idCard.length() != 18 && idCard.length() != 15) {
            throw new IllegalArgumentException("身份证号长度错误");
        }
        if (
                !"0".equals(idCard.substring(0, 1))
                && idCard.substring(0, 17).matches("^[0-9]*$")
                && DateUtil.parse(idCard.substring(6, 14), "yyyyMMdd").before(new Date())
                && DateUtil.parse(idCard.substring(6, 14), "yyyyMMdd").after(DateUtil.parse("19000101", "yyyyMMdd"))
                && modIdCard(idCard) == lastIdCard(idCard)
        ){
            return true;
        }
        return false;
    }

    /**
     * 获取身份证号余数
     * @param idCard
     * @return
     */
    public static int modIdCard(String idCard){
        int i = Integer.valueOf(idCard.substring(0, 1)) * 7 +
        Integer.valueOf(idCard.substring(1, 2)) * 9 +
        Integer.valueOf(idCard.substring(2, 3)) * 10 +
        Integer.valueOf(idCard.substring(3, 4)) * 5 +
        Integer.valueOf(idCard.substring(4, 5)) * 8 +
        Integer.valueOf(idCard.substring(5, 6)) * 4 +
        Integer.valueOf(idCard.substring(6, 7)) * 2 +
        Integer.valueOf(idCard.substring(7, 8)) * 1 +
        Integer.valueOf(idCard.substring(8, 9)) * 6 +
        Integer.valueOf(idCard.substring(9, 10)) * 3 +
        Integer.valueOf(idCard.substring(10, 11)) * 7 +
        Integer.valueOf(idCard.substring(11, 12)) * 9 +
        Integer.valueOf(idCard.substring(12, 13)) * 10 +
        Integer.valueOf(idCard.substring(13, 14)) * 5 +
        Integer.valueOf(idCard.substring(14, 15)) * 8 +
        Integer.valueOf(idCard.substring(15, 16)) * 4 +
        Integer.valueOf(idCard.substring(16, 17)) * 2;
        return i % 11;
    }

    /**
     * 获取身份证号最后一位对应的余数
     * @param idCard
     * @return
     */
    public static int lastIdCard(String idCard){
        switch (idCard.substring(17, 18)){
            case "1":
                return 0;
            case "0":
                return 1;
            case "X":
                return 2;
            case "x":
                return 2;
            case "9":
                return 3;
            case "8":
                return 4;
            case "7":
                return 5;
            case "6":
                return 6;
            case "5":
                return 7;
            case "4":
                return 8;
            case "3":
                return 9;
            case "2":
                return 10;
            default:
                return 11;
        }
    }
}
